/*
 * Copyright (C) 2022, KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

import QtQuick 2.12
import QtQuick.Layouts 1.12
import org.ukui.sidebar.core 1.0
import org.ukui.sidebar.items 1.0
import QtGraphicalEffects 1.0

Item {
    id:root;

    property int radius: 24
    property int index: 0

    property string appName: "";
    property string id: "";
    property string notificationIcon: "";
    property string summary: "";
    property string body: "";
    property string timeStamp: "";
    property string tips: qsTr("%1 more message");

    property bool groupFold: false;
    // GeneralBackground
    property double itemAlpha: 0.85;

    scale: 0.1;
    z: index;
    visible: true;

    Component.onCompleted: {
        if (!isNotificationCenter) {
            updateLayout();
            layoutConfig.layoutChanged.connect(updateLayout);
        }
    }

    Component.onDestruction: {
        layoutConfig.layoutChanged.disconnect(updateLayout);
    }

    function updateLayout() {
        radius = layoutConfig.radius(LayoutComponent.NotificationItem);
        layout.anchors.leftMargin = layoutConfig.margin(LayoutComponent.NotificationItem, 0);
        layout.anchors.topMargin = layoutConfig.margin(LayoutComponent.NotificationItem, 1);
        layout.anchors.rightMargin = layoutConfig.margin(LayoutComponent.NotificationItem, 2);
        layout.anchors.bottomMargin = layoutConfig.margin(LayoutComponent.NotificationItem, 3);

        name.height = layoutConfig.height(LayoutComponent.NotificationItemNormal);
        summary.Layout.preferredHeight = layoutConfig.height(LayoutComponent.NotificationItemNormal);
        foldTips.Layout.preferredHeight = layoutConfig.height(LayoutComponent.NotificationItemNormal);
        body.Layout.preferredHeight = layoutConfig.height(LayoutComponent.NotificationItemBody);
    }

    function updateTips() {
        if (index > 1) {
            tips =  qsTr("%1 more messages");
            foldTips.text = tips.arg(index);
        } else {
            tips =  qsTr("%1 more message");
            foldTips.text = tips.arg(index);
        }
    }

    function itemClean() {
        root.destroy(); //销毁控件
        notificationManager.deleteMessage(root.id,root.appName);
    }

    function syncItemDelete() {
        root.parent = null;
        root.destroy();
    }

    // 折叠、展开状态切换后  消息条位置重置
    function reset() {
        messageItem.x = 0;
        removeButton.opacity = 0;
        removeButton.visible = false;
    }

    Behavior on y {
        NumberAnimation {
            easing.type: Easing.InOutCubic
            duration: 300;
        }
    }

    Behavior on scale {
        NumberAnimation {
            duration: 150;
        }
    }

    NumberAnimation {
        id: alphaAnimation;
        target: root;
        property: "itemAlpha";
        duration: 300;
        from: 1.0;
        to: 0.85;
        easing.type: Easing.InQuart
    }

    // 剩余消息提示、顶部消息透明度变化
    onGroupFoldChanged: {
        if(groupFold) {
            updateTips();
        } else {
            if(itemAlpha === 1.0) {
                alphaAnimation.start();
            }
        }
    }

    Item {
        id: maskBackground;

        anchors.fill: parent;

        layer.enabled: isOpenGLEnv;
        layer.effect: OpacityMask {
            maskSource: Rectangle {
                width: maskBackground.width;
                height: maskBackground.height;
                radius: root.radius;
            }
        }

        StyleBackground {
            id: messageItem;

            width: parent.width;
            height: parent.height;
            radius: root.radius;
            visible: true;

            useStyleTransparency: false;
            paletteRole: PaletteRole.Base
            alpha: isOpenGLEnv ? root.itemAlpha : 1;

            RowLayout {
                id: layout;

                anchors.fill: parent;
                anchors.leftMargin: 16;
                anchors.topMargin: 16;
                anchors.rightMargin: 16;
                // 这个地方加上4像素的边框是为了将tips隐藏起来，不太优雅
                anchors.bottomMargin: 4;

                spacing: 8;
                clip: true;

                Item {
                    Layout.preferredWidth: 24;
                    Layout.fillHeight: true;
                    ThemeIcon {
                        id: messageIcon;
                        height: 24;
                        width: 24;
                        anchors.top: parent.top;
                        source: root.notificationIcon;
                    }
                }

                ColumnLayout {
                    id: itemColumnLayout;
                    Layout.fillWidth: true;
                    Layout.fillHeight: true;

                    spacing: 8;

                    Item {
                        Layout.fillWidth: true;
                        Layout.preferredHeight: name.height;
                        Layout.alignment: Qt.AlignVCenter;
                        StyleText {
                            id: name;
                            text: root.appName;
                            height: 24;
                            width: parent.width - time.width - 8; // 8是name与time之间的间距
                            anchors.left: parent.left;
                            elide: Text.ElideRight; //文本省略
                            maximumLineCount: 1;
                            textFormat: Text.PlainText;
                        }

                        StyleText {
                            id: time;
                            text: dateTimeUtils.computeTimeOut(root.timeStamp);
                            height: name.height;
                            visible: true;
                            maximumLineCount: 1;
                            textFormat: Text.PlainText;
                            anchors.right: parent.right;
                            Component.onCompleted: {
                                dateTimeUtils.timeRefresh.connect(refreshTimeStamp);
                                dateTimeUtils.dateUpdate.connect(refreshTimeStamp);
                                dateTimeUtils.timeUpdate.connect(refreshTimeStamp);
                            }
                            Component.onDestruction: {
                                dateTimeUtils.timeRefresh.disconnect(refreshTimeStamp);
                                dateTimeUtils.dateUpdate.disconnect(refreshTimeStamp);
                                dateTimeUtils.timeUpdate.disconnect(refreshTimeStamp)
                            }
                            function refreshTimeStamp() {
                                time.text = dateTimeUtils.computeTimeOut(root.timeStamp);
                            }
                        }
                    }

                    StyleText {
                        id: summary;

                        Layout.fillWidth: true;
                        Layout.preferredHeight: 24;
                        Layout.alignment: Qt.AlignVCenter;

                        text: root.summary;
                        font.bold: true;
                        height: 24;
                        elide: Text.ElideRight; //文本省略
                        maximumLineCount: 1;
                        textFormat: Text.PlainText;
                    }

                    StyleText {
                        id: body;

                        Layout.fillWidth: true;
                        Layout.preferredHeight: 24;
                        Layout.alignment: Qt.AlignVCenter;

                        text: root.body;
                        height: 24;
                        Layout.maximumWidth: width;
                        elide: Text.ElideRight; //文本省略
                        maximumLineCount: 1;
                        textFormat: Text.PlainText;
                    }

                    StyleText {
                        id: foldTips;

                        Layout.fillWidth: true;
                        Layout.preferredHeight: 24;
                        Layout.alignment: Qt.AlignVCenter;

                        font.pixelSize: 16;
                        maximumLineCount: 1;
                        textFormat: Text.PlainText;
                    }

                    // 占位Item， 用于向上挤压布局内容
                    Item {
                        Layout.fillWidth: true;
                        Layout.fillHeight: true;
                    }
                }
            }

            MouseArea {
                height: messageItem.height;
                width: messageItem.width;
                // 当item被隐藏或者处于折叠状态时，不启用悬浮
                hoverEnabled: !groupFold || root.visible;
                visible: !isNotificationCenter;

                onEntered: {
                    time.visible = false;
                    closeButton.visible = true;
                }

                onExited: {
                    time.visible = true;
                    closeButton.visible = false;
                }
            }
        }
        // PC鼠标悬浮，消息条右上角删除按钮
        GeneralButton {
            id: closeButton;
            width: 24;
            height: width;
            radius: 16;
            visible: false;
            z: 1;

            anchors.top: messageItem.top;
            anchors.topMargin: 6;
            anchors.right: messageItem.right;
            anchors.rightMargin: 6;
            iconName: "window-close-symbolic"

            layer.enabled: isOpenGLEnv;
            layer.effect: DropShadow {
                visible: false;
                radius: 8.0;
                samples: 20
                color: "#808080";
            }
            onClicked: {
                layer.enabled = isOpenGLEnv;
                if(!groupFold) {
                    disappeared.start();
                }
            }
            onEntered: {
                closeButton.visible = true;
                layer.enabled = isOpenGLEnv;
                time.visible = false;
            }
            onExited: {
                layer.enabled = false;
            }
        }

        StyleBackground  {
            id: removeButton;
            height: parent.height;
            width: height;
            radius: width /2;
            visible: false;
            useStyleTransparency: false;
            opacity: 0;

            anchors.right: parent.right;

            // 深色主题下反色
            HighlightIcon {
                height: 24;
                width: height;
                anchors.centerIn: parent;
                forceHighlight: true;

                iconName: "window-close-symbolic";
            }

            MouseArea {
                anchors.fill: parent;
                hoverEnabled: true;
                visible: removeButton.visible;

                function restore() {
                    removeButton.alpha = 0.85;
                }

                onClicked: {
                    disappeared.start();
                }
                onEntered: {
                    removeButton.alpha = 1.0;
                }
                onExited: {
                    restore();
                }
                onPressed: {
                    removeButton.alpha = 0.65;
                }
                onReleased: {
                    restore();
                }
                onCanceled: {
                    restore();
                }
            }

            Behavior on opacity {
                PropertyAnimation {
                    duration: 400;
                    easing.type: Easing.Linear;
                }
            }
        }

        MouseArea {
            id: drag;
            height: parent.height;
            width: removeButton.visible ? (parent.width - removeButton.width): parent.width;
            enabled: !groupFold;
            propagateComposedEvents: false;
            state: "ViewMove";

            property int dragStartX: 0 ; //鼠标起始位置
            property int dragStartY: 0;
            property int dragItemX: 0 ; //消息条起始位置
            property bool moveState: false; //移动状态 false--没有在移动

            //根据鼠标滑动x、y变化量 --->消息条左右位移、listview上下滑动
            function move() {
                //没有鼠标按下事件时，进行左右移动和上下移动的判断
                if (!moveState) {
                    if (Math.abs(mouseX - dragStartX) > 3 || Math.abs(mouseY - dragStartY) > 3) {
                        if (Math.abs(mouseX - dragStartX) > Math.abs(mouseY - dragStartY)) {
                            drag.state = "ItemMove";
                        } else {
                            drag.state = "ViewMove";
                        }
                        moveState = true;
                    }
                }
            }

            states: [
                State {
                    name: "ItemMove"
                    PropertyChanges {
                        target: drag;
                        preventStealing: true;
                    }
                },
                State {
                    name: "ViewMove"
                    PropertyChanges {
                        target: drag;
                        preventStealing: false;
                    }

                }
            ]

            onClicked: {
                mouse.accepted = false;
            }

            onPressed: {
                moveState = false;
                dragStartX = mouseX;
                dragStartY = mouseY;
                dragItemX = messageItem.x;
            }

            //随消息条位置变化，删除按钮的显示
            onPositionChanged: {
                move();
                if (drag.state === "ItemMove") {
                    messageItem.x = Math.floor(dragItemX + (mouseX - dragStartX));

                    if (messageItem.x < -removeButton.width) {
                        removeButton.visible = true;
                        removeButton.opacity = 0.85;
                    }
                    else {
                        removeButton.opacity = 0;
                        removeButton.visible = false;
                    }
                }
            }

            onReleased: {
                drag.state = "ViewMove";
                //鼠标相对位移量小 ==》 点击事件  --> 进入消息，并删除该消息条
                if (Math.abs(mouseX - dragStartX) < 3 &&0 < mouseY && mouseY< messageItem.height ) {
                    drag.propagateComposedEvents = true;
                    if(groupFold === false && messageItem.x === 0) {
                        if(notificationManager.action(root.id)) {
                            itemClean();
                            if(isNotificationCenter) {
                                notificationEventBridge.notificationHide();
                            }
                        }
                    }
                } else {
                    drag.propagateComposedEvents = false;
                    //鼠标位移量大 ==》 拖动  --> 消息条位移
                    if (messageItem.x >= -removeButton.width / 2) {
                        //右滑返回
                        back.start();
                        removeButton.opacity = 0;
                        removeButton.visible = false;

                    } else if ( messageItem.x < -removeButton.width / 2 && messageItem.x > -messageItem.width / 3 ) {
                        //小幅左滑显示删除按钮
                        appear.start();
                        removeButton.opacity = 0.85;
                        removeButton.visible = true;

                    } else {
                        //大幅左滑直接删除，不显示删除按钮
                        moved.start();
                        removeButton.opacity = 0;
                        removeButton.visible = false;
                    }
                }
            }
        }

        NumberAnimation {
            id: back;
            target: messageItem;
            properties: "x";
            to: 0;
            duration: 400;
        }

        NumberAnimation {
            id: appear;
            target: messageItem;
            properties: "x";
            to: -(removeButton.width + 8);
            duration: 400;
        }

        NumberAnimation {
            id: moved;
            target: messageItem;
            properties: "x";
            to: - messageItem.width;
            duration: 400;

            onFinished: {
                itemClean();
            }
        }

        NumberAnimation {
            id: disappeared;
            target: root;
            properties: "scale";
            to: 0;
            duration: 400;

            onFinished: {
                itemClean();
            }
        }
    }
}
